/**
 * 异步操作优化的 Composable
 * 基于 VueUse 的 useAsyncState 模式，提供统一的异步操作管理
 */
import { ref, shallowRef, computed } from 'vue'
import { message } from 'ant-design-vue'

/**
 * 通用的异步状态管理
 * @param {Function} asyncFn - 异步函数
 * @param {any} initialState - 初始状态
 * @param {Object} options - 配置选项
 */
export function useAsyncState(asyncFn, initialState, options = {}) {
  const {
    immediate = true,
    onSuccess,
    onError,
    resetOnExecute = true
  } = options

  const state = shallowRef(initialState)
  const loading = ref(false)
  const error = ref(null)

  const execute = async (...args) => {
    try {
      loading.value = true
      error.value = null

      if (resetOnExecute) {
        state.value = initialState
      }

      const result = await asyncFn(...args)
      state.value = result

      if (onSuccess) {
        onSuccess(result)
      }

      return result
    } catch (err) {
      error.value = err
      if (onError) {
        onError(err)
      }
      throw err
    } finally {
      loading.value = false
    }
  }

  const isReady = computed(() => !loading.value && error.value === null)

  if (immediate) {
    execute()
  }

  return {
    state,
    loading,
    error,
    execute,
    isReady
  }
}

/**
 * 带自动重试的异步操作
 * @param {Function} asyncFn - 异步函数
 * @param {Object} options - 配置选项
 */
export function useAsyncRetry(asyncFn, options = {}) {
  const {
    retries = 3,
    retryDelay = 1000,
    backoffMultiplier = 2,
    ...asyncOptions
  } = options

  const retryCount = ref(0)
  const { state, loading, error, execute, isReady } = useAsyncState(
    async (...args) => {
      try {
        const result = await asyncFn(...args)
        retryCount.value = 0 // 重置重试计数
        return result
      } catch (err) {
        if (retryCount.value < retries) {
          retryCount.value++
          const delay = retryDelay * Math.pow(backoffMultiplier, retryCount.value - 1)

          console.warn(`操作失败，${delay}ms 后进行第 ${retryCount.value} 次重试:`, err.message)

          return new Promise((resolve, reject) => {
            setTimeout(async () => {
              try {
                const result = await asyncFn(...args)
                retryCount.value = 0
                resolve(result)
              } catch (retryErr) {
                reject(retryErr)
              }
            }, delay)
          })
        }
        throw err
      }
    },
    null,
    asyncOptions
  )

  return {
    state,
    loading,
    error,
    execute,
    isReady,
    retryCount
  }
}

/**
 * 分页数据管理
 * @param {Function} fetchFn - 获取数据的函数
 * @param {Object} initialPagination - 初始分页配置
 */
export function usePaginationState(fetchFn, initialPagination = {}) {
  const pagination = ref({
    current: 1,
    pageSize: 20,
    total: 0,
    showSizeChanger: true,
    showQuickJumper: true,
    showTotal: (total) => `共 ${total} 条数据`,
    ...initialPagination
  })

  const filters = ref({})

  const { state, loading, error, execute, isReady } = useAsyncState(
    async () => {
      const params = {
        page: pagination.value.current,
        page_size: pagination.value.pageSize,
        ...filters.value
      }

      const response = await fetchFn(params)
      pagination.value.total = response.total
      return response.items
    },
    [],
    { immediate: false }
  )

  const load = (newFilters = {}) => {
    filters.value = { ...filters.value, ...newFilters }
    return execute()
  }

  const refresh = () => execute()

  const handlePaginationChange = (newPagination) => {
    pagination.value.current = newPagination.current
    pagination.value.pageSize = newPagination.pageSize
    return execute()
  }

  const handleFilterChange = (newFilters = {}) => {
    pagination.value.current = 1 // 重置到第一页
    filters.value = { ...filters.value, ...newFilters }
    return execute()
  }

  return {
    data: state,
    loading,
    error,
    pagination,
    filters,
    load,
    refresh,
    handlePaginationChange,
    handleFilterChange,
    isReady
  }
}

/**
 * 防抖操作
 * @param {Function} fn - 要防抖的函数
 * @param {number} delay - 延迟时间（毫秒）
 */
export function useDebounce(fn, delay = 300) {
  let timeoutId = null

  const debouncedFn = (...args) => {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => fn(...args), delay)
  }

  const cancel = () => {
    clearTimeout(timeoutId)
  }

  return {
    debouncedFn,
    cancel
  }
}

/**
 * 节流操作
 * @param {Function} fn - 要节流的函数
 * @param {number} delay - 延迟时间（毫秒）
 */
export function useThrottle(fn, delay = 300) {
  let lastCall = 0

  const throttledFn = (...args) => {
    const now = Date.now()
    if (now - lastCall >= delay) {
      lastCall = now
      return fn(...args)
    }
  }

  return {
    throttledFn
  }
}

/**
 * 批量操作管理
 * @param {Function} batchFn - 批量操作函数
 * @param {Object} options - 配置选项
 */
export function useBatchOperation(batchFn, options = {}) {
  const {
    batchSize = 10,
    delay = 100,
    onProgress,
    onComplete,
    onError
  } = options

  const processing = ref(false)
  const progress = ref(0)
  const total = ref(0)

  const executeBatch = async (items) => {
    processing.value = true
    progress.value = 0
    total.value = items.length

    try {
      const results = []
      const errors = []

      for (let i = 0; i < items.length; i += batchSize) {
        const batch = items.slice(i, i + batchSize)

        try {
          const batchResult = await batchFn(batch)
          results.push(...batchResult)
        } catch (err) {
          errors.push(err)
          if (onError) {
            onError(err, batch)
          }
        }

        progress.value = Math.min(i + batchSize, items.length)
        if (onProgress) {
          onProgress(progress.value, total.value)
        }

        // 添加延迟以避免过快的请求
        if (i + batchSize < items.length) {
          await new Promise(resolve => setTimeout(resolve, delay))
        }
      }

      if (errors.length > 0) {
        throw new Error(`批量操作完成，但有 ${errors.length} 个错误`)
      }

      if (onComplete) {
        onComplete(results)
      }

      return results
    } finally {
      processing.value = false
    }
  }

  return {
    processing,
    progress,
    total,
    executeBatch
  }
}

/**
 * 错误处理和重试机制
 * @param {Function} fn - 可能出错的函数
 * @param {Object} options - 配置选项
 */
export function useErrorHandler(fn, options = {}) {
  const {
    maxRetries = 3,
    retryDelay = 1000,
    fallbackValue = null,
    showMessage = true,
    customErrorHandler
  } = options

  const errorCount = ref(0)
  const lastError = ref(null)

  const executeWithErrorHandling = async (...args) => {
    try {
      const result = await fn(...args)
      errorCount.value = 0
      lastError.value = null
      return result
    } catch (err) {
      errorCount.value++
      lastError.value = err

      if (customErrorHandler) {
        customErrorHandler(err, errorCount.value)
      } else if (showMessage) {
        message.error(`操作失败: ${err.message}`)
      }

      if (errorCount.value <= maxRetries) {
        console.warn(`操作失败，将在 ${retryDelay}ms 后重试 (${errorCount.value}/${maxRetries}):`, err)
        await new Promise(resolve => setTimeout(resolve, retryDelay))
        return executeWithErrorHandling(...args)
      }

      console.error('操作最终失败:', err)
      return fallbackValue
    }
  }

  return {
    executeWithErrorHandling,
    errorCount,
    lastError
  }
}